home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / LIB / DESK / CORE / Desk / h_doc / Save < prev    next >
Text File  |  1996-05-21  |  12KB  |  299 lines

  1. /*
  2.     ####             #    #     # #
  3.     #   #            #    #       #          The FreeWare C library for
  4.     #   #  ##   ###  #  # #     # ###             RISC OS machines
  5.     #   # #  # #     # #  #     # #  #   ___________________________________
  6.     #   # ####  ###  ##   #     # #  #
  7.     #   # #        # # #  #     # #  #    Please refer to the accompanying
  8.     ####   ### ####  #  # ##### # ###    documentation for conditions of use
  9.     ________________________________________________________________________
  10.  
  11.     File:    save.h
  12.     Author:  Copyright © 1994 Julian Smith and Jason Howat
  13.     Version: 1.02 (18 Jun 1994)
  14.     Purpose: Automate handling of save-as windows
  15.     Mods:    13-Jun-1994 - JPS - Added filetype handling
  16.              18-Jun-1994 - JDH - See Save.c
  17. */
  18.  
  19. #ifndef __Desk_Save_h
  20. #define __Desk_Save_h
  21.  
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25.  
  26. #include <stdlib.h>
  27.  
  28. #ifndef __Desk_Event_h
  29.     #include "Desk.Event.h"
  30. #endif
  31.  
  32.  
  33.  
  34. typedef Desk_bool (*Desk_save_filesaver)(char *f, void *ref);
  35. /* 
  36. This type of function should save data to file given by 'f', using info
  37. in 'ref'. It should return Desk_bool_TRUE if it was successful. 'ref' is the (void
  38. *) originally passed to Desk_Save_InitSaveWindowHandler
  39. */
  40.  
  41. typedef int (*Desk_save_ramsaver)(
  42.   Desk_task_handle  sourcetask,                  /* our task handle */
  43.   void         *ref,
  44.   Desk_task_handle  desttask,
  45.   void         *destbuffer,
  46.   unsigned int buffersize,
  47.   int          progress       /* how many bytes have been transfered so far  */
  48.   );
  49. /*
  50. This type of function should Desk_Wimp_TransferBlock data. Note that you can
  51. do this using multiple Desk_Wimp_TransferBlock's if this is more convinient.
  52. Should return the total number of bytes transfered into 'destbuffer' -
  53. if less than buffersize, then transfer has finished. If <0, error has
  54. occurred. 'ref' is the (void *) originally passed to
  55. Desk_Save_InitSaveWindowHandler
  56. */
  57.  
  58.  
  59.  
  60.  
  61. typedef enum
  62. {
  63.   Desk_save_SAVEOK    = 0,
  64.   Desk_save_RECEIVERFAILED,
  65.   Desk_save_FILESAVERFAILED,
  66.   Desk_save_RAMSAVERFAILED
  67. } Desk_save_result;
  68.  
  69.  
  70. typedef void (*Desk_save_resulthandler)(Desk_save_result result, void *ref);
  71. /* Called after any attempt to save. */
  72.  
  73. typedef struct
  74. {
  75.   Desk_window_handle    window;        /*  Window that the save icons are in */
  76.  
  77.   union
  78.   {
  79.     unsigned int  value;
  80.     struct
  81.     {
  82.       unsigned int  Desk_is_menu         : 1;  /* Savewindow is part of menu  */
  83.       unsigned int  Desk_is_save_window  : 1;  /* Close window after save?    */
  84.       unsigned int  Desk_we_are_dragging : 1;  /* Are we dragging file icon?  */
  85.       unsigned int  Desk_quit_after_save : 1;  /* Click/drag was with Select  */
  86.       unsigned int  Desk_release_after   : 1;  /* Release all handlers when   */
  87.                                           /* the window/menu is closed?  */
  88.       unsigned int  padding         : 27;
  89.     } data;
  90.   } flags;
  91.  
  92.   Desk_icon_handle         dragsprite;
  93.   Desk_icon_handle         okbutton;
  94.   Desk_icon_handle         cancelbutton;
  95.   Desk_icon_handle         filenameicon;
  96.   Desk_save_filesaver      filesaver;
  97.   Desk_save_ramsaver       ramsaver;
  98.   Desk_save_resulthandler  resulthandler;
  99.   size_t              estimatedsize;
  100.   int                 filetype;
  101.   void                *ref;
  102.   int                 Desk_ram_progress;          /* Num of bytes ram-transfered. */
  103.   unsigned int        Desk_last_message_ref;      /* So we know which incoming    */
  104.                                              /* messages are replies to us   */
  105. } Desk_save_saveblock;
  106. /*
  107.  
  108. This struct contains all the info needed to deal with saving using the
  109. RISC OS data transfer protocol.
  110.  
  111. It is used internally by the Desk_Save_* functions - you shouldn't need to
  112. use it normally. It is included here because Desk_Save_InitSaveWindowHandler
  113. returns a pointer to it, so that you can call
  114. Desk_Save_ReleaseSaveWindowHandler if you are using RO2 and have to detect
  115. menu closing manually, and also you might want to change the field 'ref'
  116. if the user presses a 'Selection' button in the save window (you might
  117. also want to change 'filesaver' and 'ramsaver' in this case).
  118.  
  119. Also, you could change 'Desk_is_menu' if a menu-leaf savewindow changes into
  120. to a free-standing savewindow (this will only work if you have
  121. .flags.data.Desk_release_after = Desk_bool_FALSE - the saveblock wil be free-ed and all
  122. Desk_Event_ handlers released when the menu is closed otherwise.
  123.  
  124. fn 'filesaver' is called when the data needs to be saved to a file.
  125.  
  126. fn 'ramsaver' is called when the data needs to be RAM transfered.
  127.  
  128. 'ref' is passed to file/ramsaver - it should enable these functions to
  129. save the right piece of data.
  130.  
  131. You can change the following things after you have called
  132. Desk_Save_InitSaveWindowHandler:
  133.  
  134. Desk_is_menu, Desk_is_save_window, filesaver, ramsaver, resulthandler,
  135. estimatedsize, ref.
  136.  
  137. Don't change any of the icon or window handles, as these will have been
  138. used with Desk_Event_Claim, so if you change them, when Desk_Save_* calls
  139. Desk_Event_Release, DeskLib will complain.
  140.  
  141. Also, don't change any other fields (there is no reason to anyway) as
  142. these are used internally and are assumed to be const.
  143. */
  144.  
  145.  
  146.  
  147. Desk_save_saveblock *Desk_Save_InitSaveWindowHandler(
  148.   Desk_window_handle      window,           /* handle of the window to deal with  */
  149.   Desk_bool               Desk_is_menu,          /* is this window part of a menu?     */
  150.                                        /* if Desk_bool_TRUE Desk_Save_* will close it after */
  151.                                        /* 'Select'-saves                     */
  152.   Desk_bool               Desk_is_save_window,   /* is this window just a save window? */
  153.                                        /* if Desk_bool_TRUE Desk_Save_* will close it after */
  154.                                        /* 'Select'-saves                     */
  155.   Desk_bool               Desk_release_after,    /* release all Desk_Save_ handlers when    */
  156.                                        /* window/menu is closed?             */
  157.   Desk_icon_handle        dragsprite,       /* handle of the dragable file-icon   */
  158.   Desk_icon_handle        okbutton,         /* handle of 'OK' or 'Save' button    */
  159.   Desk_icon_handle        cancelbutton,     /* handle of the 'Cancel' button      */
  160.   Desk_icon_handle        filenameicon,     /* handle of the writable fname icon  */
  161.   Desk_save_filesaver     filesaver,        /* fn which saves data to a file      */
  162.   Desk_save_ramsaver      ramsaver,         /* fn which does Desk_Wimp_TransferBlocks  */
  163.   Desk_save_resulthandler resulthandler,    /* fn to report success of save to    */
  164.   size_t             estimatedsize,    /* size of data  (estimate)           */
  165.   int                filetype,
  166.   void      *ref                       /* ref passed to all saver functions  */
  167.   );
  168. /*
  169.  
  170. To implement RISC OS saving, call this function - it does all the
  171. message handling needed, and calls 'filesaver' or 'ramsaver' when
  172. needed, passing 'ref' to them so that they know what needs saving.
  173.  
  174. 'ismenu' should be Desk_bool_TRUE if 'window' is part of a menu tree, and Desk_bool_FALSE if
  175. 'window' is normal window. This is used to know when to stop handling
  176. the save, e.g. when menu is closed, or when save-window is closed.
  177.  
  178.  
  179. Things you need to do:
  180.  
  181. Create a conventional save-window with icons for Save, Cancel, and
  182. dragging, and an *indirected* text icon for the filename. (e.g. put this
  183. in a 'Templates' file). The filename icon *must* be indirected.
  184.  
  185. Put a default file/leafname in to the filename icon.
  186.  
  187. Make the dragable icon be whatever file-icon is appropriate
  188.  
  189. Write a function which can save the data to a file.  *Required*
  190.  
  191. Write a function which can Desk_Wimp_TransferBlock the data.  *Optional*
  192.  
  193. Write a function to be called with result of any save  *Optional*
  194.  
  195. Create a reference, 'ref', to the data so that the saver functions know
  196. what data to save.
  197.  
  198. Call Desk_Save_InitSaveWindowHandler You can do this anytime - e.g. just
  199. before/after you create a menu that includes the save window, when you
  200. open the save box in response to (for e.g.) a F3 keypress, or when you
  201. receive a Desk_message_MENUWARNING which heralds the opening of your
  202. save-window.
  203.  
  204.  
  205. YOU are responsible for opening the savewindow and dealing with menu
  206. handling. All Desk_Save_* does is handle the sprite-drgging, button pressing
  207. and data transfer protocol which originate in the save window.
  208.  
  209. Then, when the user tries to save the data, the only thing which you get
  210. to know about is that either your 'filesaver' or 'ramsaver' is called,
  211. with the 'ref' you originally passed to Desk_Save_InitSaveWindowHandler. If a
  212. save is attempted, 'resulthandler' will be called, with the
  213. success/failure of the save.
  214.  
  215. Thats it.
  216.  
  217.  
  218. Notes:
  219.  
  220. The 'filenameicon' may be altered by Desk_Save_InitSaveWindowHandler - it
  221. replaces the first control chr by ASCII 0, as this works with standard C
  222. functions, and some template text icons seem to be terminated by ASCII
  223. 13.
  224.  
  225. if you use 'Desk_release_after = Desk_bool_FALSE', the Desk_Event_ handlers will still be in
  226. place after the window/menu has closed. This is so you can keep a single
  227. window for all saves, and register it with Desk_Save_ just once when your
  228. application starts up. If your application deals with different pieces
  229. of data, you'll have to update the 'ref' field in the Desk_Save_saveblock
  230. returned by Desk_Save_InitSaveWindowHandler each time the window is opened.
  231.  
  232. Desk_Save_* registers a handler for when the save window is closed, which
  233. Desk_Event_Release's all of the Desk_Save_* handlers for drag/click/message
  234. handling etc. This means you can have a save window with a close icon as
  235. well as/instead of the 'cancel' icon, and makes the whole thing a bit
  236. more robust.
  237.  
  238. You can miss out any of the icons in the window by using a negative icon
  239. handle. This will prevent any Desk_Event_Claim's for the icon.
  240.  
  241. If 'ramsaver' == NULL, then 'filesaver' will always be used. If
  242. 'resulthandler' == NULL, a default handler will be used, which will do
  243. an 'Desk_Error_Report' if a save fails.
  244.  
  245. If 'resulthandler' != NULL, it will be called after any attempt to save
  246. the data, with 'ref' and one of the following flags:
  247.  
  248. Desk_save_SAVEOK = 0    receiver signals the save went OK
  249. Desk_save_SAVERECEIVERFAILED  receiver didn't signal it has received the data
  250. Desk_save_SAVESAVERFAILED  your 'filesaver' function signalled an error
  251. Desk_save_SAVERAMFAILED  your 'ramsaver'  function signalled an error
  252.  
  253. This is so that your app doesn't go away thinking data has been saved
  254. when it hasn't. Note that your saver functions will not be aware of any
  255. problem in the second case, where the receiver fails to load the scrap
  256. file.
  257.  
  258. If you want to implement a 'Selection' button in the save window, you
  259. should register a separate handler for Desk_event_CLICK on the 'Selection'
  260. button in the save window, and when it is pressed, modify the saveblock
  261. previously returned by Desk_Save_InitSaveWindowHandler, so that
  262. Desk_save_saveblock.ref points to the selction data. You could also change
  263. the writable icon contents and the 'file/ramsave' functions etc etc.
  264.  
  265. */
  266.  
  267.  
  268.  
  269. void Desk_Save_ReleaseSaveHandlers(Desk_save_saveblock *saveblock);
  270. /*
  271. You shouldn't need this normally because menu/window closing is detected
  272. by SaveBoxHandler, 'cos it detects Desk_message_MENUSDELEATED and
  273. Desk_event_CLOSE. NB, in RO2, there is no Desk_message_MENUSDELEATED, so you will
  274. have to call this function when you next open a menu, or something...
  275.  
  276. Also, if you want to close a free-standing (i.e. not in a menu)
  277. save-window when <Escape> is pressed, you will need this function.
  278.  
  279. */
  280.  
  281. void Desk_Save_SetFiletype(Desk_save_saveblock *saveblock, int filetype);
  282. /*
  283. Sets the sprite in the savewindow to be "Desk_file_..." and also alters the
  284. saveblock so that the filetype is used whenever date is saved to the
  285. filer  or another application.    
  286.                     
  287. NB this function changes the dragsprite icon is an *undirected* sprite-
  288. -only icon. If it was previously an indirected icon, the pointer to the 
  289. indirected data is lost forever!                    
  290. */
  291.  
  292. #ifdef __cplusplus
  293. }
  294. #endif
  295.  
  296.  
  297. #endif
  298.  
  299.